package city.spring.configure.mybatis.handler;

import city.spring.configure.SequenceKey;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.jdbc.core.JdbcTemplate;

import java.lang.reflect.Field;

/**
 * MyBatis 自动填充一个 SequenceKey 主键ID
 *
 * @author HouKunLin
 * @date 2020/7/15 0015 15:46
 */
public class SequenceKeyMetaObjectHandlerImpl implements IMetaObjectHandler {
    private final IKeyGenerator keyGenerator;
    private final JdbcTemplate jdbcTemplate;

    public SequenceKeyMetaObjectHandlerImpl(IKeyGenerator keyGenerator, JdbcTemplate jdbcTemplate) {
        this.keyGenerator = keyGenerator;
        this.jdbcTemplate = jdbcTemplate;
    }

    private Object getFieldVal(Field field, Long value) {
        Object fieldVal = null;
        Class<?> type = field.getType();
        if (type.isAssignableFrom(String.class)) {
            fieldVal = value.toString();
        } else if (type.isAssignableFrom(Long.class)) {
            fieldVal = value;
        } else if (type.isAssignableFrom(Integer.class)) {
            fieldVal = value.intValue();
        }
        return fieldVal;
    }

    @Override
    public boolean run(MetaObjectHandler metaObjectHandler, MetaObject metaObject, Field field) {
        TableField tableField = field.getAnnotation(TableField.class);
        SequenceKey sequenceKey = field.getAnnotation(SequenceKey.class);
        if (tableField != null && sequenceKey != null && tableField.fill() == FieldFill.INSERT) {
            Long key = jdbcTemplate.queryForObject(keyGenerator.executeSql(sequenceKey.value()), Long.class);
            if (key == null) {
                return false;
            }
            metaObject.setValue(field.getName(), getFieldVal(field, key));
            return true;
        }
        return false;
    }
}
